﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System.Collections.Generic;

using BlobTowerDefense.Pages;
using BlobTowerDefense.Managers;
using BlobTowerDefense.Tools;

using Matrix = Microsoft.Xna.Framework.Matrix;
using System.Globalization;
using BlobTowerDefense.Game_Entities;

namespace BlobTowerDefense.Tools
{
    /// <summary>
    /// Load information about new worlds, enemies and Towers for load to managers
    /// This class is becouse it will be better to read and  modify
    /// </summary>
    public class Loader
    {
        private WorldManager worldManager;
        //private EnemyManager enemyManager;
        //private GraphicsDevice device;

//        public Loader(WorldManager world, EnemyManager enemy, GraphicsDevice device)
        public Loader(WorldManager world)
        {
            worldManager = world;
            //enemyManager = enemy;
            //this.device = GamePage.Device;
        }

        /// <summary>
        /// Load data which is needed to load worlds
        /// </summary>
        public void FillWorldData()
        {
            //float aspectRation = (float)device.Viewport.Width / (float)device.Viewport.Height;
            //float fov = MathHelper.PiOver4;

            //Matrix projection = Matrix.CreatePerspectiveFieldOfView(fov, aspectRation, 1, 1000);
            //Matrix view = Matrix.CreateLookAt(new Vector3(0.0f, 5.0f, 10.0f), new Vector3(0.0f, 0.0f, 0.0f), new Vector3(0.0f, 1.0f, 0.0f));

            Vector3[] buildingPositions_lvl1 = new Vector3[] { 
                new Vector3(-48.0f, -10.0f, 2.0f), //zacatek
                new Vector3(-48.0f, -5.0f, 2.0f),
                new Vector3(-48.0f,  0.0f, 2.0f),
                new Vector3(-48.0f,  5.0f, 2.0f),

                new Vector3(-45.0f,  13.0f, 2.0f), //horni rada
                new Vector3(-40.0f,  13.0f, 2.0f),
                new Vector3(-35.0f,  13.0f, 2.0f),
                new Vector3(-30.0f,  13.0f, 2.0f),

                new Vector3(-15.0f,  13.0f, 2.0f),
                new Vector3(-10.0f,  13.0f, 2.0f),
                new Vector3(-5.0f,  13.0f, 2.0f),
                new Vector3( 0.0f,  13.0f, 2.0f),

                new Vector3(13.0f,  13.0f, 2.0f),
                new Vector3(18.0f,  13.0f, 2.0f),
                new Vector3(23.0f,  13.0f, 2.0f),
                new Vector3(28.0f,  13.0f, 2.0f),

                new Vector3(42.0f,  13.0f, 2.0f),
                new Vector3(47.0f,  13.0f, 2.0f),  //konec horni rady

                new Vector3(-41.0f, -18.0f, 2.0f), //spodni rada
                new Vector3(-33.0f, -18.0f, 2.0f),

                new Vector3(-26.0f, -21.0f, 2.0f),
                new Vector3(-20.0f, -21.0f, 2.0f),

                new Vector3(-13.0f, -18.0f, 2.0f),
                new Vector3(-5.0f, -18.0f, 2.0f),

                new Vector3(2.0f, -21.0f, 2.0f),
                new Vector3(8.0f, -21.0f, 2.0f),

                new Vector3(15.0f, -18.0f, 2.0f),
                new Vector3(23.0f, -18.0f, 2.0f),

                new Vector3(30.0f, -21.0f, 2.0f),
                new Vector3(36.0f, -21.0f, 2.0f), //konec spodni rady

                new Vector3(-40.0f,  5.0f, 2.0f), //u horni cesty
                new Vector3(-34.0f,  5.0f, 2.0f),

                new Vector3(-12.0f, 5.0f, 2.0f),
                new Vector3(-6.0f,  5.0f, 2.0f),

                new Vector3(16.0f, 5.0f, 2.0f),
                new Vector3(22.0f,  5.0f, 2.0f), //konec u horni cesty

                new Vector3(-26.0f, -13.0f, 2.0f), //u spodni cesty
                new Vector3(-20.0f, -13.0f, 2.0f),

                new Vector3(2.0f, -13.0f, 2.0f), 
                new Vector3(8.0f, -13.0f, 2.0f),

                new Vector3(30.0f, -13.0f, 2.0f), 
                new Vector3(36.0f, -13.0f, 2.0f), //konec u spodni cesty

                new Vector3(-33.0f,  -1.0f, 2.0f), //podel cest
                new Vector3(-33.0f, -11.0f, 2.0f),

                new Vector3(-27.0f,  3.0f, 2.0f),
                new Vector3(-27.0f, -7.0f, 2.0f),

                new Vector3(-19.0f,  3.0f, 2.0f),
                new Vector3(-19.0f, -7.0f, 2.0f),

                new Vector3(-13.0f,  -1.0f, 2.0f),
                new Vector3(-13.0f, -11.0f, 2.0f),

                new Vector3(-5.0f,  -1.0f, 2.0f),
                new Vector3(-5.0f, -11.0f, 2.0f),

                new Vector3(1.0f,  3.0f, 2.0f),
                new Vector3(1.0f, -7.0f, 2.0f),

                new Vector3(9.0f,  3.0f, 2.0f),
                new Vector3(9.0f, -7.0f, 2.0f),

                new Vector3(15.0f,  -1.0f, 2.0f),
                new Vector3(15.0f, -11.0f, 2.0f),
                
                new Vector3(23.0f,  -1.0f, 2.0f),
                new Vector3(23.0f, -11.0f, 2.0f),
                
                new Vector3(29.0f,  3.0f, 2.0f),
                new Vector3(29.0f, -7.0f, 2.0f),

                new Vector3(37.0f,  3.0f, 2.0f),
                new Vector3(37.0f, -7.0f, 2.0f)
            };
            Vector3[] buildingScales_lvl1 = new Vector3[] { 
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f)
            };

            Vector3[] buildingPositions_lvl2 = new Vector3[] { 
                new Vector3(-41.0f, -18.0f, 2.0f), //spodni cast
                new Vector3(-41.0f, -13.0f, 2.0f),
                new Vector3(-41.0f, -7.0f, 2.0f),
                new Vector3(-41.0f, -2.0f, 2.0f),
                new Vector3(-41.0f,  3.0f, 2.0f),
                new Vector3(-41.0f,  8.0f, 2.0f),
                new Vector3(-41.0f,  13.0f, 2.0f),
                new Vector3(-41.0f,  18.0f, 2.0f),
                new Vector3(-41.0f,  23.0f, 2.0f),
  
                new Vector3(-35.0f, -18.0f, 2.0f),
                new Vector3(-35.0f, -13.0f, 2.0f),
                new Vector3(-35.0f, -7.0f, 2.0f),
                new Vector3(-35.0f,  -2.0f, 2.0f),
                new Vector3(-35.0f,  3.0f, 2.0f),
                new Vector3(-35.0f,  8.0f, 2.0f),
                new Vector3(-35.0f,  13.0f, 2.0f),
                new Vector3(-35.0f,  18.0f, 2.0f),

                new Vector3(-35.0f, 18.0f, 2.0f),
                new Vector3(-30.0f, 18.0f, 2.0f),
                new Vector3(-25.0f, 18.0f, 2.0f),
                new Vector3(-20.0f, 13.0f, 2.0f),
                new Vector3(-15.0f, 13.0f, 2.0f),
                new Vector3(-10.0f, 13.0f, 2.0f),
                new Vector3(-5.0f,  13.0f, 2.0f),

                new Vector3(-24.0f, -18.0f, 2.0f),
                new Vector3(-24.0f, -13.0f, 2.0f),
                new Vector3(-24.0f, -7.0f, 2.0f),
                new Vector3(-24.0f,  -2.0f, 2.0f),
                new Vector3(-24.0f,  3.0f, 2.0f),

                new Vector3(-17.0f, -18.0f, 2.0f),
                new Vector3(-17.0f, -13.0f, 2.0f),
                new Vector3(-17.0f, -7.0f, 2.0f),
                new Vector3(-17.0f,  -2.0f, 2.0f),

                new Vector3(-12.0f, -18.0f, 2.0f),
                new Vector3(-7.0f, -18.0f, 2.0f),
                new Vector3(-7.0f, 1.0f, 2.0f),

                new Vector3(8.0f, 18.0f, 6.0f), //horni cast
                new Vector3(13.0f, 18.0f, 6.0f),
                new Vector3(18.0f, 18.0f, 6.0f),
                new Vector3(23.0f, 18.0f, 6.0f),
                new Vector3(28.0f, 18.0f, 6.0f),
                new Vector3(33.0f, 18.0f, 6.0f),
                new Vector3(43.0f,  18.0f, 6.0f),

                new Vector3(8.0f, 8.0f, 6.0f),
                new Vector3(13.0f, 8.0f, 6.0f),
                new Vector3(18.0f, 8.0f, 6.0f),
                new Vector3(23.0f, 8.0f, 6.0f),
                new Vector3(28.0f, 8.0f, 6.0f),
                new Vector3(33.0f, 8.0f, 6.0f),

                new Vector3(8.0f, 1.0f, 6.0f),
                new Vector3(13.0f, 1.0f, 6.0f),
                new Vector3(18.0f, 1.0f, 6.0f),
                new Vector3(23.0f, 1.0f, 6.0f),
                new Vector3(28.0f, 1.0f, 6.0f),
                new Vector3(33.0f, 1.0f, 6.0f),

                new Vector3(8.0f, -11.0f, 6.0f),
                new Vector3(13.0f, -11.0f, 6.0f),
                new Vector3(18.0f, -11.0f, 6.0f),
                new Vector3(23.0f, -11.0f, 6.0f),
                new Vector3(28.0f, -11.0f, 6.0f),
                new Vector3(33.0f, -11.0f, 6.0f),

                new Vector3(13.0f, -18.0f, 6.0f),
                new Vector3(18.0f, -18.0f, 6.0f),
                new Vector3(23.0f, -18.0f, 6.0f),

                new Vector3(33.0f, -16.0f, 6.0f),
                new Vector3(43.0f, -16.0f, 6.0f),
                new Vector3(35.0f, -5.0f, 6.0f)

            };
            Vector3[] buildingScales_lvl2 = new Vector3[] { 
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f),
                new Vector3(1.0f)
            };

            // Set info needed to load level - default matrices will be set to identity (without view matrix)
            worldManager.AddLoadInfo(@"Levels\level1", "Level 1", 0, Camera.ViewMatrix, buildingPositions_lvl1, buildingScales_lvl1);
            worldManager.AddLoadInfo(@"Levels\level2", "Level 2", 1, Camera.ViewMatrix, buildingPositions_lvl2, buildingScales_lvl2);

            // Set default projection matrix to all loaded worlds
            worldManager.SetProjToAll(Camera.ProjectionMatrix);
        }

        /// <summary>
        /// Load data needed to create enemies
        /// </summary>
/*        public void FillEnemiesData()
        {
            float aspectRation = (float)device.Viewport.Width / (float)device.Viewport.Height;
            float fov = MathHelper.PiOver4;

            Matrix projection = Matrix.CreatePerspectiveFieldOfView(fov, aspectRation, 1, 1000);
            Matrix view = Matrix.CreateLookAt(new Vector3(0.0f, 5.0f, 10.0f), new Vector3(0.0f, 0.0f, 0.0f), new Vector3(0.0f, 1.0f, 0.0f));

            List<EnemyToLoad> enemies = new List<EnemyToLoad>();
            List<Vector3> checkpoints = new List<Vector3>();

            // create enemies
            // enemy type --- time when to create enemy
            enemies.Add(new EnemyToLoad(ENEMYTYPE.BALL1, 2));
            enemies.Add(new EnemyToLoad(ENEMYTYPE.BALL1, 2));
            enemies.Add(new EnemyToLoad(ENEMYTYPE.BALL1, 2));
            enemies.Add(new EnemyToLoad(ENEMYTYPE.BALL1, 2));
            enemies.Add(new EnemyToLoad(ENEMYTYPE.BALL1, 2));

            // create checkpoints witch set way for enemies to move
            checkpoints.Add(new Vector3(0, 0, 0));
            checkpoints.Add(new Vector3(1, 0, 1));
            checkpoints.Add(new Vector3(5, 0, 5));

            // load this information to manager
            enemyManager.LoadWorldEnemies(enemies);
            enemyManager.SetCheckpointsToAll(checkpoints);


            // At the end

            // Set default projection and view matrix to all loaded data
            enemyManager.SetDefViewProj(projection, view);

            // Set enemies from first world as active
            enemyManager.setActiveWorld(0);

        }
*/
        /// <summary>
        /// Load all data needed 
        /// </summary>
        public void FillAllData()
        {
            FillWorldData();
            //FillEnemiesData();
        }

        public static bool Load_LeftHanded()
        {
            if (App.AppSettings.Contains("LeftHanded"))
            {
                return (bool) App.AppSettings["LeftHanded"];
            }
            else
            {
                return DefaultSettings.Lefthanded_Default;
            }
        }

        public static double Load_Sensitivity()
        {
            if (App.AppSettings.Contains("Sensitivity"))
            {
                return (double)App.AppSettings["Sensitivity"];
            }
            else
            {
                return DefaultSettings.Sensitivity_Default;
            }
        }

        public static short Load_MasterVolume_Current()
        {
            if (App.AppSettings.Contains("MasterVolume_Current"))
            {
                return (short)App.AppSettings["MasterVolume_Current"];
            }
            else
            {
                return DefaultSettings.VolumeMaster_Current_Default;
            }
        }

        public static short Load_MusicVolume_Current()
        {
            if (App.AppSettings.Contains("MusicVolume_Current"))
            {
                return (short)App.AppSettings["MusicVolume_Current"];
            }
            else
            {
                return DefaultSettings.VolumeMusic_Current_Default;
            }
        }

        public static short Load_SoundsVolume_Current()
        {
            if (App.AppSettings.Contains("SoundsVolume_Current"))
            {
                return (short)App.AppSettings["SoundsVolume_Current"];
            }
            else
            {
                return DefaultSettings.VolumeSounds_Current_Default;
            }
        }

        public static short Load_MasterVolume_Previous()
        {
            if (App.AppSettings.Contains("MasterVolume_Previous"))
            {
                return (short)App.AppSettings["MasterVolume_Previous"];
            }
            else
            {
                return DefaultSettings.VolumeMaster_Previous_Default;
            }
        }

        public static short Load_MusicVolume_Previous()
        {
            if (App.AppSettings.Contains("MusicVolume_Previous"))
            {
                return (short)App.AppSettings["MusicVolume_Previous"];
            }
            else
            {
                return DefaultSettings.VolumeMusic_Previous_Default;
            }
        }

        public static short Load_SoundsVolume_Previous()
        {
            if (App.AppSettings.Contains("SoundsVolume_Previous"))
            {
                return (short)App.AppSettings["SoundsVolume_Previous"];
            }
            else
            {
                return DefaultSettings.VolumeSounds_Previous_Default;
            }
        }

        public static CultureInfo Load_Culture()
        {
            if (App.AppSettings.Contains("Culture"))
            {
                return (CultureInfo)App.AppSettings["Culture"];
            }
            else
            {
                return DefaultSettings.Culture_Default;
            }
        }

        /*
        public static Dictionary<string, int> Load_HighScores()
        {
            string[] names = (string[]) App.AppSettings["HighScore_Names"];
            int[] scores = (int[])App.AppSettings["HighScore_Scores"];

            Dictionary<string, int> toReturn = new Dictionary<string, int>(names.Length);

            for(int i = 0; i < names.Length; i++)
            {
                toReturn.Add(names[i], scores[i]);
            }

            return toReturn;
        }
        */

        public static string[] Load_HighScore_Names()
        {
            if (App.AppSettings.Contains("HighScore_Names"))
            {
                return (string[])App.AppSettings["HighScore_Names"];
            }
            else
            {
                return null;
            }
        }

        public static int[] Load_HighScore_Scores()
        {
            if (App.AppSettings.Contains("HighScore_Scores"))
            {
                return (int[])App.AppSettings["HighScore_Scores"];
            }
            else
            {
                return null;
            }
        }

        public static string Load_NickName()
        {
            if (App.AppSettings.Contains("NickName"))
            {
                return (string)App.AppSettings["NickName"];
            }
            else
            {
                return "";
            }
        }

        public static GamePage Load_GamePage()
        {
            if (App.AppSettings.Contains("GamePage_Saved"))
            {
                return (GamePage)App.AppSettings["GamePage_Saved"];
            }
            else
            {
                return null;
            }
        }

        public static WAVETYPE? Load_SavedWaveType()
        {
            if (App.AppSettings.Contains("SavedWaveType"))
            {
                return (WAVETYPE)App.AppSettings["SavedWaveType"];
            }
            else
            {
                return null;
            }
        }

        public static DIFFICULTY? Load_SavedDifficulty()
        {
            if (App.AppSettings.Contains("SavedDifficulty"))
            {
                return (DIFFICULTY)App.AppSettings["SavedDifficulty"];
            }
            else
            {
                return null;
            }
        }

        public static int Load_SavedPlayerHP()
        {
            if (App.AppSettings.Contains("SavedPlayerHP"))
            {
                return (int)App.AppSettings["SavedPlayerHP"];
            }
            else
            {
                return 1;
            }
        }

        public static int Load_SavedPlayerMoney()
        {
            if (App.AppSettings.Contains("SavedPlayerMoney"))
            {
                return (int)App.AppSettings["SavedPlayerMoney"];
            }
            else
            {
                return 0;
            }
        }

        public static List<Tower> Load_SavedTowers()
        {
            if (App.AppSettings.Contains("SavedTowers"))
            {
                return (List<Tower>)App.AppSettings["SavedTowers"];
            }
            else
            {
                return null;
            }
        }
    }
}
